﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.ObjectExtending;

namespace EcoSystem
{
    public class SystemRoleAppService : ApplicationService, ISystemRoleAppService
    {

        public IRepository<IdentityRole, Guid> RoleRepository { get; set; }

        public async Task<IdentityRoleDto> CreateAsync(IdentityRoleDto input)
        {
            var entity = ObjectMapper.Map<IdentityRoleDto, IdentityRole>(input);
            entity.ExtraProperties.Clear();
            foreach (var item in input.ExtraProperties)
            {
                entity.ExtraProperties.Add(item.Key, item.Value);
            }
            EntityHelper.TrySetId(entity, () => GuidGenerator.Create());
            await RoleRepository.InsertAsync(entity, true);
            return ObjectMapper.Map<IdentityRole, IdentityRoleDto>(entity);
        }

        public async Task<ListResultDto<IdentityRoleDto>> GetAllListAsync(GetIdentityRolesInput input)
        {
            var query = (await RoleRepository.GetQueryableAsync()).AsNoTracking();
            query = query.WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Filter));
            var items = await query.OrderByDescending(x => x.Id).ToListAsync();
            return new ListResultDto<IdentityRoleDto>()
            {
                Items = items.Select(x =>
                {
                    var dtoItem = ObjectMapper.Map<IdentityRole, IdentityRoleDto>(x);
                    foreach (var item in x.ExtraProperties)
                    {
                        dtoItem.ExtraProperties.Add(item.Key, item.Value);
                    }
                    return dtoItem;
                }).ToList()
            };
        }

        public async Task<IdentityRoleDto> GetAsync(Guid id)
        {
            var entity = await RoleRepository.GetAsync(id, true);
            var result = ObjectMapper.Map<IdentityRole, IdentityRoleDto>(entity);
            foreach (var item in entity.ExtraProperties)
            {
                result.ExtraProperties.Add(item.Key, item.Value);
            }
            return result;

        }

        public async Task<PagedResultDto<IdentityRoleDto>> GetListAsync(GetIdentityRolesInput input)
        {
            var query = (await RoleRepository.GetQueryableAsync()).AsNoTracking();
            query = query.WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Filter));
            var totalCount = await query.CountAsync();
            var items = await query.OrderByDescending(x => x.Id).PageBy(input).ToListAsync();
            return new PagedResultDto<IdentityRoleDto>()
            {
                TotalCount = totalCount,
                Items = items.Select(x =>
                {
                    var dtoItem = ObjectMapper.Map<IdentityRole, IdentityRoleDto>(x);
                    foreach (var item in x.ExtraProperties)
                    {
                        dtoItem.ExtraProperties.Add(item.Key, item.Value);
                    }
                    return dtoItem;
                }).ToList()
            };

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<IdentityRoleDto> UpdateAsync(Guid id, IdentityRoleDto input)
        {

            var entity = await RoleRepository.GetAsync(id, true);
            entity.IsDefault = input.IsDefault;
            entity.IsPublic = input.IsPublic;
            entity.IsStatic = input.IsStatic;
            entity.ExtraProperties.Clear();
            foreach (var item in input.ExtraProperties)
            {
                entity.ExtraProperties.Add(item.Key, item.Value);
            }
            await RoleRepository.UpdateAsync(entity, true);
            return ObjectMapper.Map<IdentityRole, IdentityRoleDto>(entity);
        }
    }
}
